package com.example.occlusiondemo.activity;

import static com.example.occlusiondemo.activity.StartActivity.isDebug;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.SeekBar;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.eqgis.eqtool.tmp.Utils;
import com.example.occlusiondemo.PathConfig;
import com.example.occlusiondemo.R;
import com.example.occlusiondemo.view.DynamicView;
import com.supermap.ar.areffect.OcclusionHelperPlus;
import com.supermap.ar.areffect.excavator.CeilingExcavator;
import com.supermap.ar.areffect.excavator.ExcavationParameter;
import com.supermap.ar.areffect.excavator.Excavator;
import com.supermap.ar.areffect.excavator.GroundExcavator;
import com.supermap.ar.areffect.excavator.BasePitObject;
import com.supermap.ar.areffect.excavator.WallExcavator;
import com.supermap.ar.areffect.ErrorCallback;
import com.supermap.ar.areffect.loader.ModelGroupScene;
import com.google.are.sceneform.math.Quaternion;
import com.google.are.sceneform.math.Vector3;
import com.supermap.ar.Point3D;
import com.supermap.ar.areffect.AREffectElement;
import com.supermap.ar.areffect.AREffectView;
import com.supermap.ar.areffect.EffectView;
import com.supermap.ar.areffect.Location;
import com.supermap.ar.areffect.OcclusionHelper;
import com.supermap.ar.areffect.TouchResult;
import com.supermap.ar.areffect.Vector;
import com.supermap.ar.areffect.preset.ARGeoPrism;
import com.supermap.ar.areffect.preset.BaseShape;
import com.supermap.data.Environment;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 技术验证示例2：与遮挡设置APP无关
 * 墙体、天花板、地面开挖技术验证
 * <p>
 *     当前存在的问题：遮挡显示有问题
 * </p>
 */
public class PipeActivityVertical_lxk extends Activity implements EffectView.OnUpdateListener,View.OnTouchListener{
    private AREffectView arView;
    private OcclusionHelper occlusionHelper;
    private Excavator excavatorWall;
    private Excavator excavatorCeiling;
    private Excavator excavatorGround;
    private BasePitObject pitWall;
    private BasePitObject pitCeiling;
    private BasePitObject pitGround;

    private SeekBar heightSeekBar;
    private SeekBar radiusSeekBar;

    private DynamicView dynamicView;

    //管线场景集合
    private ArrayList<ModelGroupScene> modelGroupScenes = new ArrayList<>();
    private AREffectElement room;
    @Override
    protected void onDestroy() {
        super.onDestroy();
//        System.exit(0);
    }

    @Override
    protected void onPause() {
        occlusionHelper.pause();
        arView.onPause();
        super.onPause();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Utils.hideBottomUIMenu(this);
        Utils.hideTopUI(this);

        if (isDebug){
            Toast.makeText(this, "启动中", Toast.LENGTH_SHORT).show();
        }
        //设置许可
        Environment.setLicensePath(PathConfig.LICENSE_PATH);
        Environment.initialization(/*上下文*/this,/*是否是64位*/true);
        setContentView(R.layout.activity_main_vertical_lxk);


        arView = findViewById(R.id.ar_view);
        arView.setVisibleDistance(100);
        //禁用光源，防止出现阴影
        arView.getArSceneView().getScene().getSunlight().setEnabled(false);
        arView.setPlaneVisible(false);

        dynamicView = findViewById(R.id.test_view_lxk);
        dynamicView.connectView(arView);
        
        addPipeScene();

        arView.addOnUpdateListener(this::onUpdate);
        arView.setDeviceLocation(new Location(103,30,0));

        List<Point3D> roomBounds = Arrays.asList(
                new Point3D(-1, -1, -2),
                new Point3D(-1, 6, -2),
                new Point3D(6, 6, -2),
                new Point3D(6, -1, -2),
                new Point3D(-1, -1, -2)
        );
        ARGeoPrism geoVerticalRegion = new ARGeoPrism();
        geoVerticalRegion.setParentNode(arView);
        geoVerticalRegion.setRenderable(false);//不渲染出来，仅用作碰撞计算
        geoVerticalRegion.setColor(0.5f,0.5f,0.8f,0.5f);
        geoVerticalRegion.addPart(roomBounds,6.0f);

        List<Point3D> roomBounds2 = Arrays.asList(
                new Point3D(-1.02f, -1.02f, -2.02f),
                new Point3D(-1.02f, 6.02f, -2.02f),
                new Point3D(6.02f, 6.02f, -2.02f),
                new Point3D(6.02f, -1.02f, -2.02f),
                new Point3D(-1.02f, -1.02f, -2.02f)
        );

        room = new AREffectElement(this).setParentNode(arView);
        ARGeoPrism roomPrism = new ARGeoPrism();
        roomPrism.setParentNode(room);
        BaseShape baseShape = new BaseShape(BaseShape.MatType.OPAQUE);
        baseShape.setRadius(0.01f);
        roomPrism.setOutLine(baseShape);
        roomPrism.setColor(0.5f,0.5f,0.8f,0.5f);
        roomPrism.addPart(roomBounds2,6.0f);

        occlusionHelper = arView.getOcclusionHelper(true);
        occlusionHelper.init(0.52f).setRenderMode(OcclusionHelper.RenderMode.NORMAL);

        //创建开挖工具
        excavatorWall = new WallExcavator(geoVerticalRegion);
        excavatorCeiling = new CeilingExcavator(geoVerticalRegion);
        excavatorGround = new GroundExcavator(geoVerticalRegion);
        //创建坑洞渲染对象

        //纹理
        Bitmap bitmap=null;
        Bitmap bitmap2=null;
        try {
            InputStream is = getApplicationContext().getAssets().open("brown_mud_dry2.png");
            bitmap= BitmapFactory.decodeStream(is);
            InputStream is2 = getApplicationContext().getAssets().open("wall_texture.png");
            bitmap2= BitmapFactory.decodeStream(is2);
            is.close();
            is2.close();
        } catch (IOException e) {
        }
        pitWall = new BasePitObject(excavatorWall).setTexture(bitmap2,bitmap);
        pitCeiling = new BasePitObject(excavatorCeiling).setTexture(bitmap2,bitmap);
        pitGround = new BasePitObject(excavatorGround).setTexture(bitmap2,bitmap);
        initUI();
    }

    @SuppressLint("UseSwitchCompatOrMaterialCode")
    private void initUI() {
        heightSeekBar = findViewById(R.id.height_seekbar);
        heightSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                TextView textView = findViewById(R.id.height_seekbar_txt);
                textView.setText(""+progress+"mm");
//                updatePitObj(lastEvent);
            }

            @SuppressLint("SetTextI18n")
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });
        radiusSeekBar = findViewById(R.id.radius_seekbar);
        radiusSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                TextView textView = findViewById(R.id.radius_seekbar_txt);
                textView.setText(""+progress+"mm");
//                updatePitObj(lastEvent);
            }

            @SuppressLint("SetTextI18n")
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {

            }
        });

        Switch pipeSwitch = (Switch) findViewById(R.id.gltf_switch);
        pipeSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
            for (int i = 0; i < modelGroupScenes.size(); i++) {
                ModelGroupScene scene = modelGroupScenes.get(i);
                scene.getSceneElement().setVisiblity(isChecked);
            }
        });

        Switch roomSwitch = (Switch) findViewById(R.id.prism_switch);
        roomSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> {
            room.setVisiblity(isChecked);
        });

        ((Switch)findViewById(R.id.occlusion_switch)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                occlusionHelper.setEnabled(isChecked);
            }
        });
        occlusionHelper.setEnabled(true);//默认开启

//        ((Switch)findViewById(R.id.touch_switch)).setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
//            @Override
//            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
//                if (isChecked){
//                    arView.getForegroundView().setOnTouchListener(PipeActivityVertical_lxk.this::onTouch);
//                }else {
//                    arView.getForegroundView().setOnTouchListener(null);
//                }
//            }
//        });
    }


    @Override
    public void onUpdate() {
        updatePitObj(arView.getWidth()/2,arView.getHeight()/2);
        if (occlusionHelper.isEnabled()){
            //desc-执行画面裁剪
            ArrayList<int[]> screenPoint;
            if (excavatorWall !=null){
                screenPoint = excavatorWall.getScreenPoint(null);
                if (screenPoint!=null){
                    occlusionHelper.setUniquePointList(screenPoint).refresh();

                    dynamicView.updateLine(screenPoint);
                }
            }
            if (excavatorGround !=null){
                screenPoint = excavatorGround.getScreenPoint(null);
                if (screenPoint!=null){
                    occlusionHelper.setUniquePointList(screenPoint).refresh();
                    dynamicView.updateLine(screenPoint);
                }
            }
            if (excavatorCeiling !=null){
                screenPoint = excavatorCeiling.getScreenPoint(null);
                if (screenPoint!=null){
                    occlusionHelper.setUniquePointList(screenPoint).refresh();
                    dynamicView.updateLine(screenPoint);
                }
            }
        }
    }

    private MotionEvent lastEvent;
    @Override
    public boolean onTouch(View v, MotionEvent event) {
//        updatePitObj(event);
        return true;
    }

    private void updatePitObj(int x,int y) {
//        if (event == null)return;
        //通过touch交互获取屏幕坐标，进而计算碰撞点。碰撞结果可为空
        float offset = (float) heightSeekBar.getProgress() / 100.0f;
        float radius = (float) radiusSeekBar.getProgress() / 100.0f;
        //墙面
        Point3D hitPoint = excavatorWall.generateHitPoint(arView, x,y);
        if (hitPoint!=null){
            //desc-执行开挖的顶点计算
            excavatorWall.calculate(/*开挖参数*/ExcavationParameter.builder()
                    .setRadius(radius).setOffset(offset).setInnerMargin(0.02f).setCenterPoint(hitPoint).build());

//            lastEvent = event;
        }
        //渲染坑洞结果
        pitWall.updateMesh();

        //地面
        hitPoint = excavatorGround.generateHitPoint(arView,  x,y);
        if (hitPoint!=null){
            //desc-执行开挖的顶点计算
            excavatorGround.calculate(/*开挖参数*/ExcavationParameter.builder()
                    .setRadius(radius).setOffset(offset).setInnerMargin(0.02f).setCenterPoint(hitPoint)
                    .setFixedDirection(new Vector(0,1,0))
                    .build());

//            lastEvent = event;
        }
        //渲染坑洞结果
        pitGround.updateMesh();

        //天花板
        hitPoint = excavatorCeiling.generateHitPoint(arView,  x,y);
        if (hitPoint!=null){
            //desc-执行开挖的顶点计算
            excavatorCeiling.calculate(/*开挖参数*/ExcavationParameter.builder()
                    .setRadius(radius).setOffset(offset).setInnerMargin(0.02f).setCenterPoint(hitPoint)
                    .setFixedDirection(new Vector(0,1,0))
                    .build());

//            lastEvent = event;
        }
        //渲染坑洞结果
        pitCeiling.updateMesh();
    }


    /***********=-=-=-=-=-=-=-=-=-=-数据加载=-=-=-=-=-=-=-=-=-=-**********************/
    /**
     * 加载管线场景
     */
    private void addPipeScene() {
        ModelGroupScene modelGroupScene = new ModelGroupScene(arView);
        modelGroupScene.getSceneElement().setRotationAngle(new Quaternion(Vector3.down(),-90));
        modelGroupScene.getSceneElement().setPosition(new Point3D(-1,4,0));
        modelGroupScene.setOnClickEnabled(true);
        modelGroupScene.setOnClickListener(new ModelGroupScene.OnClickListener() {
            @Override
            public void onClick(AREffectElement element, TouchResult touchResult) {
                if (isDebug){
                    com.eqgis.eqtool.tmp.VibrateHelper.vSimple(getApplicationContext(),100);
                    Toast.makeText(PipeActivityVertical_lxk.this, "点中了\"" + element.getElementName() +"\"", Toast.LENGTH_SHORT).show();
                    modelGroupScene.unSelectAll();
                    element.select();
                }
            }
        });
        modelGroupScene.loadModelFolder(PathConfig.VERTICAL_PIPE_DATA, "GLB", new ErrorCallback() {
            @Override
            public void onError(Error error) {
                if (error == null){
                    modelGroupScenes.add(modelGroupScene);
                }
            }
        });

        ModelGroupScene modelGroupScene2 = new ModelGroupScene(arView);
        modelGroupScene2.getSceneElement().setPosition(new Point3D(4,6.5f,0));
        modelGroupScene2.setOnClickEnabled(true);
        modelGroupScene2.setOnClickListener(new ModelGroupScene.OnClickListener() {
            @Override
            public void onClick(AREffectElement element, TouchResult touchResult) {
                if (isDebug){
                    com.eqgis.eqtool.tmp.VibrateHelper.vSimple(getApplicationContext(),100);
                    Toast.makeText(PipeActivityVertical_lxk.this, "点中了\"" + element.getElementName() +"\"", Toast.LENGTH_SHORT).show();
                    modelGroupScene.unSelectAll();
                    element.select();
                }
            }
        });
        modelGroupScene2.loadModelFolder(PathConfig.VERTICAL_PIPE_DATA, "GLB", new ErrorCallback() {
            @Override
            public void onError(Error error) {
                if (error == null){
                    modelGroupScenes.add(modelGroupScene2);
                }
            }
        });

        ModelGroupScene modelGroupScene3 = new ModelGroupScene(arView);
        modelGroupScene3.getSceneElement().setPosition(new Point3D(1,5,4));
        modelGroupScene3.loadModelFolder(PathConfig.TOP_PIPE_DATA, "GLB", new ErrorCallback() {
            @Override
            public void onError(Error error) {
                if (error == null){
                    modelGroupScenes.add(modelGroupScene3);
                }
            }
        });

        ModelGroupScene modelGroupScene4 = new ModelGroupScene(arView);
        modelGroupScene4.getSceneElement().setPosition(new Point3D(3,2,-2));
        modelGroupScene4.getSceneElement().setRotationAngle(new Quaternion(Vector3.up(),90));
        modelGroupScene4.loadModelFolder(PathConfig.UNDERGROUND_PIPE_DATA, "GLB", new ErrorCallback() {
            @Override
            public void onError(Error error) {
                if (error == null){
                    modelGroupScenes.add(modelGroupScene4);
                }
            }
        });
    }

}
